package com.runmonk.core.study.concurrent.thread_test;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


/**
 * CountDownLatch测试类demo
 * 如何使用CountDownLatch，使用countDown()、await()
 */
public class CountDownLatchTest {

    /**
     * 测试主线程
     *
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {

        /**
         * 测试demo1----------------------------------------------------------------------------------------------------->>>>>>>>>>>>>
         */
//        CountDownLatch countDown = new CountDownLatch(1);
//        CountDownLatch await = new CountDownLatch(5);
//
//        // 依次创建并启动处于等待状态的5个MyRunnable线程
//        for (int i = 0; i < 5; ++i) {
//            new Thread(new MyRunnable(countDown, await)).start();
//        }
//        System.out.println("用于触发处于等待状态的线程开始工作......");
//        System.out.println("用于触发处于等待状态的线程工作完成，等待状态线程开始工作......");
//
//        countDown.countDown();
//        await.await();//主线程等待子线程 执行完
//        System.out.println("Bingo!");


        /**
         * 测试demo2----------------------------------------------------------------------------------------------------->>>>>>>>>>>>>
         */
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 100, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(5));
        int count = 10;
        final CountDownLatch latch = new CountDownLatch(count);

        for (int i = 0; i < count; i++) {
            threadPool.execute(new MyRunnable1(latch, i));
        }

        latch.await();//等待子线程完成
        System.err.println("等待线程被唤醒！");
        threadPool.shutdown();
    }


}

/**
 * 测试线程1 myRunnable
 */
class MyRunnable implements Runnable {

    private final CountDownLatch countDown;
    private final CountDownLatch await;

    public MyRunnable(CountDownLatch countDown, CountDownLatch await) {
        this.countDown = countDown;
        this.await = await;
    }

    public void run() {
        try {
            countDown.await();//等待主线程执行完毕，获得开始执行信号...
            System.out.println("处于等待的线程开始自己预期工作......");
            await.countDown();//完成预期工作，发出完成信号...
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


/**
 * 测试线程2 myRunnable
 */
class MyRunnable1 implements Runnable {

    CountDownLatch latch = null;
    int i;

    public MyRunnable1(CountDownLatch latch, int i) {
        this.latch = latch;
        this.i = i;
    }

    @Override
    public void run() {

        try {

            System.err.println("线程" + Thread.currentThread() + i + "完成了操作...");
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        latch.countDown();
    }

}